package com.kk.datastructure.tree.availabletree.huffman;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Map;
//import static com.kk.datastructure.tree.availabletree.HuffmanCode;

/**
 * title: 赫夫曼实现文件压缩，解压
 * @author 阿K
 * 2021年1月16日 下午9:05:10 
 */
public class HuffmanFileZipDemp {

	public static void main(String[] args) {
		String s1 = "J:\\caolaoshi.avi";
		String s2 = "J:\\caolaoshi.zip";		
		String s3 = "J:\\caolaoshi(1).avi";		
		zipFile(s1, s2);
		unzipFile(s2,s3);
	}
	
	/**
	 * 文件的解压
	 * @param unzipFile
	 * @param dstFile
	 */
	public static void unzipFile(String unzipFile,String dstFile) {
		// 定义流
		FileOutputStream os = null;
		FileInputStream is = null;
		ObjectInputStream ois = null;
		
		try {
			// 初始化
			is = new FileInputStream(unzipFile);
			// 初始化对象输入流 --- 用于读入 赫夫曼表和源文件数组
			ois = new ObjectInputStream(is);
			byte[] huffmanBytes = (byte[])ois.readObject();
			Map<Byte,String> huffmanCodes = (Map<Byte,String>)ois.readObject();
			
			// 解码
			byte[] bytes = HuffmanCode.decode(huffmanCodes, huffmanBytes);
			// 将bytes 数组写入到目标文件
			os = new FileOutputStream(dstFile);
			os.write(bytes);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				os.close();
				ois.close();
				is.close();
			} catch (Exception e2) {
				System.out.println(e2.getMessage());
			}
		}
	}
	
	/**
	 * 文件压缩方法
	 * @param srcFile 准备压缩的源文件路径
	 * @param dstFile 压缩后输出的文件李静
	 */
	public static void zipFile(String srcFile, String dstFile) {
		// 定义流，这里核心使用的是对象流
		FileInputStream is = null;
		FileOutputStream os = null;
		ObjectOutputStream oos = null;

		try {
			// 初始化流
			is = new FileInputStream(srcFile);
			// 创建一个和源文件大小一致的 byte数组
			byte[] b = new byte[is.available()];
			// 将文件读取到字节数组中
			is.read(b);
			// 对源文件字节数组进行压缩,得到赫夫曼编码压缩文件
			byte[] huffmanBytes = HuffmanCode.huffmanZip(b);
			// 初始化输出流，用于输出到指定路径
			os = new FileOutputStream(dstFile);
			// 创建输出的对象流，方便后续解压，毕竟 byte 数组 就是一个对象
			oos = new ObjectOutputStream(os);
			oos.writeObject(huffmanBytes);
			// 注意：编码表也要输入，后续要对照这个进行解压
			oos.writeObject(HuffmanCode.huffmanCodes);

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
				oos.close();
				os.close();
			} catch (Exception e) {
				System.out.println(e.getMessage());
			}
		}
	}
}
